package com.zhc.validate.entity;

import com.zhc.validate.processor.AlgorithmAnnotationProcessor;
import com.zhc.validate.processor.SolutionAnnotationProcessor;
import com.zhc.validate.constants.Constant;
import lombok.Data;

import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;

/**
 * 待执行的任务
 */
@Data
public class Task {
    /**
     * 任务目标类
     */
    private Clazz clazz;
    /**
     * 任务目标方法(一组)
     */
    private Set<Algorithm> algorithms;

    /**
     * priority 越小，优先级越高
     */
    public static Queue<Task> tasks = new PriorityQueue<>(Comparator.comparingInt(o -> o.clazz.getPriority()));


    public Class<?> getClazz() {
        return clazz.getCls();
    }

    public int getPriority() {
        return clazz.getPriority();
    }

    public Method getMethod() {
        return algorithms.iterator().next().getMethod();
    }


    /*
      扫描目标包,获取所有任务
     */
    static {
        Set<Clazz> clazzes = SolutionAnnotationProcessor.processor();
        for (Clazz clazz : clazzes) {
            tasks.add(new Task(clazz, AlgorithmAnnotationProcessor.processor(clazz.getCls())));
        }
    }

    public Task(Clazz clazz, Set<Algorithm> algorithms) {
        this.clazz = clazz;
        this.algorithms = algorithms;
    }

    public String toString() {
        String className = clazz.getCls() == null ? "null" : clazz.getCls().getName();

        StringBuffer classBuffer = new StringBuffer();
        StringBuffer methodBuffer = new StringBuffer();
        StringBuffer priorityBuffer = new StringBuffer();

        classBuffer.append("    Class:\n        ").append(className).append("\n");
        methodBuffer.append("    Method:\n");
        priorityBuffer.append("    Priority:\n        ").append(clazz.getPriority()).append("\n");

        if (algorithms.isEmpty()) {
            methodBuffer.append("\n    No methods found\n");
        } else {
            for (Algorithm algorithm : algorithms) {
                methodBuffer.append("        ").append(algorithm.getMethod()).append("\n");
            }
        }
        return Constant.getTaskString(classBuffer.toString(), methodBuffer.toString(), priorityBuffer.toString(), "=================================================================================");
    }
}
